/**
 * IndexedDB存储服务
 * 支持大容量数据存储，特别适合存储图片等二进制数据
 */

export interface Folder {
  id: number
  name: string
  count: number
  isDefault?: boolean
  parentId?: number | null
}

export interface Note {
  id: number
  title: string
  content: string
  folderId: number
  createdAt: string
  updatedAt: string
  images?: string[] // 图片ID数组
}

export interface ImageData {
  id: string
  name: string
  data: Blob
  type: string
  size: number
  createdAt: string
}

export interface AppData {
  folders: Folder[]
  notes: Note[]
  currentFolder: string
  currentNoteId: number | null
}

const DB_NAME = 'LinkBookDB'
const DB_VERSION = 1
const NOTES_STORE = 'notes'
const FOLDERS_STORE = 'folders'
const IMAGES_STORE = 'images'
const SETTINGS_STORE = 'settings'

let db: IDBDatabase | null = null

/**
 * 初始化IndexedDB数据库
 * @returns Promise<IDBDatabase>
 */
export const initDB = (): Promise<IDBDatabase> => {
  return new Promise((resolve, reject) => {
    if (db) {
      resolve(db)
      return
    }

    const request = indexedDB.open(DB_NAME, DB_VERSION)

    request.onerror = () => {
      console.error('IndexedDB打开失败:', request.error)
      reject(request.error)
    }

    request.onsuccess = () => {
      db = request.result
      console.log('IndexedDB初始化成功')
      resolve(db)
    }

    request.onupgradeneeded = (event) => {
      const database = (event.target as IDBOpenDBRequest).result

      // 创建笔记存储
      if (!database.objectStoreNames.contains(NOTES_STORE)) {
        const notesStore = database.createObjectStore(NOTES_STORE, { keyPath: 'id' })
        notesStore.createIndex('folderId', 'folderId', { unique: false })
        notesStore.createIndex('title', 'title', { unique: false })
      }

      // 创建文件夹存储
      if (!database.objectStoreNames.contains(FOLDERS_STORE)) {
        database.createObjectStore(FOLDERS_STORE, { keyPath: 'id' })
      }

      // 创建图片存储
      if (!database.objectStoreNames.contains(IMAGES_STORE)) {
        const imagesStore = database.createObjectStore(IMAGES_STORE, { keyPath: 'id' })
        imagesStore.createIndex('createdAt', 'createdAt', { unique: false })
      }

      // 创建设置存储
      if (!database.objectStoreNames.contains(SETTINGS_STORE)) {
        database.createObjectStore(SETTINGS_STORE, { keyPath: 'key' })
      }

      console.log('IndexedDB数据库结构创建完成')
    }
  })
}

/**
 * 保存笔记数据
 * @param notes 笔记数组
 * @returns Promise<void>
 */
export const saveNotes = async (notes: Note[]): Promise<void> => {
  const database = await initDB()
  const transaction = database.transaction([NOTES_STORE], 'readwrite')
  const store = transaction.objectStore(NOTES_STORE)

  // 清空现有数据
  await new Promise<void>((resolve, reject) => {
    const clearRequest = store.clear()
    clearRequest.onsuccess = () => resolve()
    clearRequest.onerror = () => reject(clearRequest.error)
  })

  // 保存新数据
  for (const note of notes) {
    await new Promise<void>((resolve, reject) => {
      const request = store.put(note)
      request.onsuccess = () => resolve()
      request.onerror = () => reject(request.error)
    })
  }

  console.log(`已保存 ${notes.length} 条笔记`)
}

/**
 * 加载笔记数据
 * @returns Promise<Note[]>
 */
export const loadNotes = async (): Promise<Note[]> => {
  const database = await initDB()
  const transaction = database.transaction([NOTES_STORE], 'readonly')
  const store = transaction.objectStore(NOTES_STORE)

  return new Promise((resolve, reject) => {
    const request = store.getAll()
    request.onsuccess = () => {
      console.log(`加载了 ${request.result.length} 条笔记`)
      resolve(request.result)
    }
    request.onerror = () => reject(request.error)
  })
}

/**
 * 保存文件夹数据
 * @param folders 文件夹数组
 * @returns Promise<void>
 */
export const saveFolders = async (folders: Folder[]): Promise<void> => {
  const database = await initDB()
  const transaction = database.transaction([FOLDERS_STORE], 'readwrite')
  const store = transaction.objectStore(FOLDERS_STORE)

  // 清空现有数据
  await new Promise<void>((resolve, reject) => {
    const clearRequest = store.clear()
    clearRequest.onsuccess = () => resolve()
    clearRequest.onerror = () => reject(clearRequest.error)
  })

  // 保存新数据
  for (const folder of folders) {
    await new Promise<void>((resolve, reject) => {
      const request = store.put(folder)
      request.onsuccess = () => resolve()
      request.onerror = () => reject(request.error)
    })
  }

  console.log(`已保存 ${folders.length} 个文件夹`)
}

/**
 * 加载文件夹数据
 * @returns Promise<Folder[]>
 */
export const loadFolders = async (): Promise<Folder[]> => {
  const database = await initDB()
  const transaction = database.transaction([FOLDERS_STORE], 'readonly')
  const store = transaction.objectStore(FOLDERS_STORE)

  return new Promise((resolve, reject) => {
    const request = store.getAll()
    request.onsuccess = () => {
      console.log(`加载了 ${request.result.length} 个文件夹`)
      resolve(request.result)
    }
    request.onerror = () => reject(request.error)
  })
}

/**
 * 保存图片数据
 * @param imageData 图片数据
 * @returns Promise<string> 返回图片ID
 */
export const saveImage = async (
  imageData: Omit<ImageData, 'id' | 'createdAt'>
): Promise<string> => {
  const database = await initDB()
  const transaction = database.transaction([IMAGES_STORE], 'readwrite')
  const store = transaction.objectStore(IMAGES_STORE)

  const id = `img_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  const image: ImageData = {
    ...imageData,
    id,
    createdAt: new Date().toISOString()
  }

  return new Promise((resolve, reject) => {
    const request = store.add(image)
    request.onsuccess = () => {
      console.log(`图片已保存: ${id}, 大小: ${(imageData.size / 1024).toFixed(2)}KB`)
      resolve(id)
    }
    request.onerror = () => reject(request.error)
  })
}

/**
 * 加载图片数据
 * @param imageId 图片ID
 * @returns Promise<ImageData | null>
 */
export const loadImage = async (imageId: string): Promise<ImageData | null> => {
  const database = await initDB()
  const transaction = database.transaction([IMAGES_STORE], 'readonly')
  const store = transaction.objectStore(IMAGES_STORE)

  return new Promise((resolve, reject) => {
    const request = store.get(imageId)
    request.onsuccess = () => {
      resolve(request.result || null)
    }
    request.onerror = () => reject(request.error)
  })
}

/**
 * 删除图片数据
 * @param imageId 图片ID
 * @returns Promise<void>
 */
export const deleteImage = async (imageId: string): Promise<void> => {
  const database = await initDB()
  const transaction = database.transaction([IMAGES_STORE], 'readwrite')
  const store = transaction.objectStore(IMAGES_STORE)

  return new Promise((resolve, reject) => {
    const request = store.delete(imageId)
    request.onsuccess = () => {
      console.log(`图片已删除: ${imageId}`)
      resolve()
    }
    request.onerror = () => reject(request.error)
  })
}

/**
 * 获取所有图片列表
 * @returns Promise<ImageData[]>
 */
export const getAllImages = async (): Promise<ImageData[]> => {
  const database = await initDB()
  const transaction = database.transaction([IMAGES_STORE], 'readonly')
  const store = transaction.objectStore(IMAGES_STORE)

  return new Promise((resolve, reject) => {
    const request = store.getAll()
    request.onsuccess = () => {
      resolve(request.result)
    }
    request.onerror = () => reject(request.error)
  })
}

/**
 * 保存应用设置
 * @param key 设置键
 * @param value 设置值
 * @returns Promise<void>
 */
export const saveSetting = async (key: string, value: unknown): Promise<void> => {
  const database = await initDB()
  const transaction = database.transaction([SETTINGS_STORE], 'readwrite')
  const store = transaction.objectStore(SETTINGS_STORE)

  return new Promise((resolve, reject) => {
    const request = store.put({ key, value })
    request.onsuccess = () => resolve()
    request.onerror = () => reject(request.error)
  })
}

/**
 * 加载应用设置
 * @param key 设置键
 * @returns Promise<any>
 */
export const loadSetting = async (key: string): Promise<unknown> => {
  const database = await initDB()
  const transaction = database.transaction([SETTINGS_STORE], 'readonly')
  const store = transaction.objectStore(SETTINGS_STORE)

  return new Promise((resolve, reject) => {
    const request = store.get(key)
    request.onsuccess = () => {
      resolve(request.result?.value || null)
    }
    request.onerror = () => reject(request.error)
  })
}

/**
 * 获取存储使用情况
 * @returns Promise<{used: number, available: number}>
 */
export const getStorageUsage = async (): Promise<{ used: number; available: number }> => {
  try {
    if ('storage' in navigator && 'estimate' in navigator.storage) {
      const estimate = await navigator.storage.estimate()
      return {
        used: estimate.usage || 0,
        available: estimate.quota || 0
      }
    }
  } catch (error) {
    console.warn('无法获取存储使用情况:', error)
  }

  return {
    used: 0,
    available: 0
  }
}

/**
 * 清除所有数据
 * @returns Promise<void>
 */
export const clearAllData = async (): Promise<void> => {
  const database = await initDB()
  const transaction = database.transaction(
    [NOTES_STORE, FOLDERS_STORE, IMAGES_STORE, SETTINGS_STORE],
    'readwrite'
  )

  const promises = [
    new Promise<void>((resolve, reject) => {
      const request = transaction.objectStore(NOTES_STORE).clear()
      request.onsuccess = () => resolve()
      request.onerror = () => reject(request.error)
    }),
    new Promise<void>((resolve, reject) => {
      const request = transaction.objectStore(FOLDERS_STORE).clear()
      request.onsuccess = () => resolve()
      request.onerror = () => reject(request.error)
    }),
    new Promise<void>((resolve, reject) => {
      const request = transaction.objectStore(IMAGES_STORE).clear()
      request.onsuccess = () => resolve()
      request.onerror = () => reject(request.error)
    }),
    new Promise<void>((resolve, reject) => {
      const request = transaction.objectStore(SETTINGS_STORE).clear()
      request.onsuccess = () => resolve()
      request.onerror = () => reject(request.error)
    })
  ]

  await Promise.all(promises)
  console.log('所有数据已清除')
}

/**
 * 导出所有数据
 * @returns Promise<{appData: AppData, images: {id: string, name: string, data: string}[]}>
 */
export const exportAllData = async (): Promise<{
  appData: AppData
  images: { id: string; name: string; data: string }[]
}> => {
  const [notes, folders, images] = await Promise.all([loadNotes(), loadFolders(), getAllImages()])

  const currentFolder = ((await loadSetting('currentFolder')) as string) || '全部笔记'
  const currentNoteId = ((await loadSetting('currentNoteId')) as number | null) || null

  // 将图片转换为base64格式
  const imageExports = await Promise.all(
    images.map(async (img) => {
      const arrayBuffer = await img.data.arrayBuffer()
      const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)))
      return {
        id: img.id,
        name: img.name,
        type: img.type,
        data: base64
      }
    })
  )

  return {
    appData: {
      folders,
      notes,
      currentFolder,
      currentNoteId
    },
    images: imageExports
  }
}
